package com.lzz.bottomencapsulation.view.activity.needone;

import android.graphics.BitmapFactory;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ZipAnimationDrawable {
    private static final String TAG = "ZipAnimationDrawable";

    public static AnimationDrawable readDrawable(String zipFileString) {
        try {
            return UnZipFileDrawable(zipFileString);
        } catch (IOException e) {
            Log.i(TAG, "readDrawable: Exception " + zipFileString);
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private static AnimationDrawable UnZipFileDrawable(String zipFileString) throws IOException {
        ZipInputStream inZip = new ZipInputStream(new FileInputStream(zipFileString));
        ZipEntry zipEntry;
        String szName = "";
        int len;
        ByteBuffer config = null;
        ArrayList<ByteArrayOutputStream> list = new ArrayList<ByteArrayOutputStream>();

        while ((zipEntry = inZip.getNextEntry()) != null) {
            szName = zipEntry.getName();
            if (zipEntry.isDirectory()) {

            } else if (szName.equals("config")) {
                ByteArrayOutputStream out = new ByteArrayOutputStream();

                int offset = 0;
                byte[] buffer = new byte[1024];
                while ((len = inZip.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
                config = ByteBuffer.wrap(out.toByteArray());
                config.order(ByteOrder.LITTLE_ENDIAN);
//                drawable = new Drawable[config.getInt()];
//                out.reset();
            } else {
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                while ((len = inZip.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
                list.add(out);
            }
        }
        Log.i(TAG, "UnZipFileDrawable: " + zipFileString);
        return convert(list, config);
    }

    private static AnimationDrawable convert(ArrayList<ByteArrayOutputStream> list, ByteBuffer
            byteBuffer) {
        int framenum, num_plays;
        int delay_time;
        if (byteBuffer == null) {
            framenum = list.size();
            num_plays = 0;
            delay_time = 0;
//            return null;
        } else {
            framenum = byteBuffer.getInt();
            num_plays = byteBuffer.getInt();
        }
        Frame[] frames = new Frame[framenum];
        ByteArrayOutputStream out;

        for (int i = 0; i < framenum; i++) {
            out = list.get(i);
            try {
                delay_time = byteBuffer.getInt(i * 4 + 8);
            } catch (Exception e) {
//                e.printStackTrace();
                delay_time = 0;
            }
            if (delay_time == 0) delay_time = 50;

            try {
//                Log.i(TAG, "convert: "+i);
                frames[i] = new Frame(delay_time, new BitmapDrawable(BitmapFactory
                        .decodeByteArray(out.toByteArray(), 0, out.size())));
            } catch (Exception e) {
                Log.i(TAG, "convert: " + i);
                e.printStackTrace();
            }
        }

        AnimationDrawable ad = new AnimationDrawable();
        int repeatSequenceCount;
        if (num_plays == 0) {
            ad.setOneShot(false);
            repeatSequenceCount = 1;
        } else {
            ad.setOneShot(true);
            repeatSequenceCount = num_plays;
        }
        for (int i = 0; i < repeatSequenceCount; i++) {
            for (Frame frame : frames) {
                ad.addFrame(frame.drawable, frame.delay_time);
            }
        }
        return ad;
    }

    private static class Frame {
        public final int delay_time;
        public final Drawable drawable;

        public Frame(int delay_time, Drawable drawable) {
            this.delay_time = delay_time;
            this.drawable = drawable;
        }
    }
}

